using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.AvalonEdit.CodeCompletion;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;

namespace AvalonEditDemo.Services
{
    /// <summary>
    /// 提供Python代码补全数据的类，实现AvalonEdit的ICompletionData接口
    /// </summary>
    public class PythonCompletionData : ICompletionData
    {
        /// <summary>
        /// 初始化PythonCompletionData的新实例
        /// </summary>
        /// <param name="text">要显示和插入的文本</param>
        /// <param name="description">对该项的描述，如果为null则使用默认描述</param>
        /// <param name="insertText">要插入的文本，如果为null则使用text参数的值</param>
        public PythonCompletionData(string text, string description = null, string insertText = null)
        {
            Text = text;
            Description = description ?? $"Python 标识符: {text}";
            InsertText = insertText ?? text;
        }

        /// <summary>
        /// 获取或设置代码补全项的图标
        /// </summary>
        public System.Windows.Media.ImageSource Image => null;

        /// <summary>
        /// 获取显示在补全列表中的文本
        /// </summary>
        public string Text { get; }

        /// <summary>
        /// 获取要插入到文档中的文本
        /// </summary>
        private string InsertText { get; }

        /// <summary>
        /// 获取补全项的内容对象
        /// </summary>
        public object Content => Text;

        /// <summary>
        /// 获取补全项的描述信息
        /// </summary>
        public object Description { get; }

        /// <summary>
        /// 获取补全项的优先级
        /// </summary>
        public double Priority => 0;

        /// <summary>
        /// 将补全项插入到文本区域
        /// </summary>
        /// <param name="textArea">要插入的文本区域</param>
        /// <param name="completionSegment">要替换的文本段</param>
        /// <param name="insertionRequestEventArgs">插入请求的事件参数</param>
        public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
        {
            textArea.Document.Replace(completionSegment, InsertText);
        }
    }

    /// <summary>
    /// 提供Python代码补全功能的服务
    /// 使用静态分析为编辑器提供智能代码补全
    /// </summary>
    public class CodeCompletionService
    {
        /// <summary>
        /// 单例实例，全局访问点
        /// </summary>
        public static CodeCompletionService Instance { get; private set; } = new CodeCompletionService();
        
        /// <summary>
        /// 当前的补全窗口
        /// </summary>
        private CompletionWindow _completionWindow;
        
        /// <summary>
        /// 当前编辑器文本，用于上下文分析
        /// </summary>
        private string _currentEditorText = string.Empty;

        /// <summary>
        /// Python关键字列表
        /// </summary>
        private static readonly string[] PythonKeywords = {
            "and", "as", "assert", "async", "await", "break", "class", "continue", 
            "def", "del", "elif", "else", "except", "False", "finally", "for", 
            "from", "global", "if", "import", "in", "is", "lambda", "None", 
            "nonlocal", "not", "or", "pass", "raise", "return", "True", "try", 
            "while", "with", "yield"
        };

        /// <summary>
        /// Python内置函数列表
        /// </summary>
        private static readonly string[] PythonBuiltins = {
            "abs", "all", "any", "ascii", "bin", "bool", "bytearray", "bytes", "callable",
            "chr", "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
            "enumerate", "eval", "exec", "filter", "float", "format", "frozenset", "getattr",
            "globals", "hasattr", "hash", "help", "hex", "id", "input", "int", "isinstance",
            "issubclass", "iter", "len", "list", "locals", "map", "max", "memoryview", "min",
            "next", "object", "oct", "open", "ord", "pow", "print", "property", "range",
            "repr", "reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod",
            "str", "sum", "super", "tuple", "type", "vars", "zip", "__import__"
        };

        /// <summary>
        /// 常用的Python代码片段
        /// </summary>
        private static readonly Dictionary<string, string> CodeSnippets = new()
        {
            {"if", "if ${condition}:\n    ${cursor}"},
            {"for", "for ${item} in ${collection}:\n    ${cursor}"},
            {"while", "while ${condition}:\n    ${cursor}"},
            {"def", "def ${function_name}(${parameters}):\n    ${cursor}"},
            {"class", "class ${class_name}:\n    def __init__(self):\n        ${cursor}"},
            {"try", "try:\n    ${cursor}\nexcept Exception as e:\n    print(f\"Error: {e}\")"},
            {"import", "import ${module}"},
            {"from", "from ${module} import ${name}"},
            {"with", "with ${expression} as ${variable}:\n    ${cursor}"},
            {"lambda", "lambda ${args}: ${expression}"},
            {"list", "[${item} for ${item} in ${collection}]"},
            {"dict", "{${key}: ${value} for ${item} in ${collection}}"},
            {"print", "print(f\"${message}\")"} 
        };

        /// <summary>
        /// 常用Python模块列表
        /// </summary>
        private static readonly string[] CommonModules = {
            "os", "sys", "math", "random", "datetime", "time", "json", "re", 
            "collections", "itertools", "functools", "threading", "multiprocessing",
            "sqlite3", "csv", "pickle", "pathlib"
        };

        /// <summary>
        /// 常用Python对象的成员，按对象类型分类
        /// </summary>
        private static readonly Dictionary<string, List<string>> CommonObjectMembers = new Dictionary<string, List<string>>
        {
            // 字符串对象成员
            {"str", new List<string> {
                "capitalize", "casefold", "center", "count", "encode", "endswith", "expandtabs",
                "find", "format", "format_map", "index", "isalnum", "isalpha", "isascii",
                "isdecimal", "isdigit", "isidentifier", "islower", "isnumeric", "isprintable",
                "isspace", "istitle", "isupper", "join", "ljust", "lower", "lstrip",
                "maketrans", "partition", "replace", "rfind", "rindex", "rjust", "rpartition",
                "rsplit", "rstrip", "split", "splitlines", "startswith", "strip", "swapcase",
                "title", "translate", "upper", "zfill"
            }},
            
            // 列表对象成员
            {"list", new List<string> {
                "append", "clear", "copy", "count", "extend", "index", "insert", "pop", "remove", "reverse", "sort"
            }},
            
            // 字典对象成员
            {"dict", new List<string> {
                "clear", "copy", "fromkeys", "get", "items", "keys", "pop", "popitem", "setdefault", "update", "values"
            }},
            
            // 集合对象成员
            {"set", new List<string> {
                "add", "clear", "copy", "difference", "difference_update", "discard", "intersection",
                "intersection_update", "isdisjoint", "issubset", "issuperset", "pop", "remove",
                "symmetric_difference", "symmetric_difference_update", "union", "update"
            }},
            
            // 文件对象成员
            {"file", new List<string> {
                "close", "closed", "encoding", "errors", "fileno", "flush", "isatty", "mode",
                "name", "read", "readable", "readline", "readlines", "seek", "seekable", "tell",
                "truncate", "writable", "write", "writelines"
            }},
            
            // datetime对象成员
            {"datetime", new List<string> {
                "now", "today", "utcnow", "fromtimestamp", "utcfromtimestamp", "fromordinal", "combine", 
                "fromisoformat", "min", "max", "resolution", "year", "month", "day", "hour", "minute", 
                "second", "microsecond", "tzinfo", "date", "time", "replace", "astimezone", "isoformat", 
                "strftime", "timestamp"
            }},
            
            // math模块成员
            {"math", new List<string> {
                "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "ceil", "comb", "copysign", 
                "cos", "cosh", "degrees", "dist", "e", "erf", "erfc", "exp", "expm1", "fabs", "factorial", 
                "floor", "fmod", "frexp", "fsum", "gamma", "gcd", "hypot", "inf", "isclose", "isfinite", 
                "isinf", "isnan", "isqrt", "lcm", "ldexp", "lgamma", "log", "log10", "log1p", "log2", "modf", 
                "nan", "perm", "pi", "pow", "prod", "radians", "remainder", "sin", "sinh", "sqrt", "tan", "tanh", "tau", "trunc"
            }}
        };

        /// <summary>
        /// 公共方法名列表，用于当无法确定对象类型时提供常见方法
        /// </summary>
        private static readonly List<string> CommonMethodNames = new List<string> {
            "__init__", "__str__", "__repr__", "__len__", "__getitem__", "__setitem__", "__delitem__", 
            "__iter__", "__next__", "__enter__", "__exit__", "__call__", "__add__", "__sub__", "__mul__", 
            "__div__", "__eq__", "__lt__", "__gt__", "get", "set", "add", "remove", "clear", "update", 
            "find", "count", "sort", "append", "insert", "pop", "convert", "parse", "format", "create", 
            "delete", "open", "close", "read", "write", "send", "receive"
        };

        /// <summary>
        /// 初始化CodeCompletionService的新实例
        /// </summary>
        private CodeCompletionService()
        {
            // 使用静态代码补全
            System.Diagnostics.Debug.WriteLine("初始化Python代码补全服务，使用静态补全");
        }

        /// <summary>
        /// 更新当前编辑器文本，用于代码分析和补全
        /// </summary>
        /// <param name="text">编辑器中的当前文本</param>
        public void UpdateEditorText(string text)
        {
            _currentEditorText = text;
        }
        
        /// <summary>
        /// 显示代码补全窗口
        /// </summary>
        /// <param name="textArea">要显示补全窗口的文本区域</param>
        public void ShowCompletionWindow(TextArea textArea)
        {
            CloseCompletionWindow();

            // 获取当前行和当前光标位置前的文本
            var line = textArea.Document.GetLineByOffset(textArea.Caret.Offset);
            var lineText = textArea.Document.GetText(line.Offset, textArea.Caret.Offset - line.Offset);

            // 确定补全段的开始
            var completionStartOffset = FindCompletionStartOffset(textArea, lineText);
            var completionSegment = new TextSegment 
            { 
                StartOffset = completionStartOffset, 
                EndOffset = textArea.Caret.Offset 
            };
            
            // 获取前缀
            var prefix = textArea.Document.GetText(completionStartOffset, textArea.Caret.Offset - completionStartOffset);

            _completionWindow = new CompletionWindow(textArea)
            {
                StartOffset = completionStartOffset,
                EndOffset = textArea.Caret.Offset,
                CloseWhenCaretAtBeginning = true
            };

            IList<ICompletionData> completionItems = _completionWindow.CompletionList.CompletionData;

            // 获取补全项列表
            var completions = GetCompletions(lineText, prefix);
            foreach (var item in completions)
            {
                completionItems.Add(item);
            }

            // 如果有补全项，显示窗口，否则关闭
            if (completionItems.Count > 0)
            {
                _completionWindow.Show();
                _completionWindow.Closed += (s, args) => _completionWindow = null;
            }
            else
            {
                _completionWindow.Close();
            }
        }

        /// <summary>
        /// 关闭当前的补全窗口
        /// </summary>
        public void CloseCompletionWindow()
        {
            if (_completionWindow != null)
            {
                _completionWindow.Close();
                _completionWindow = null;
            }
        }

        /// <summary>
        /// 查找补全开始的偏移量
        /// </summary>
        /// <param name="textArea">文本区域</param>
        /// <param name="lineText">当前行文本</param>
        /// <returns>补全应该开始的偏移量</returns>
        private int FindCompletionStartOffset(TextArea textArea, string lineText)
        {
            // 对于成员访问，如object.xxx，我们只需要匹配点后面的内容
            if (lineText.Contains("."))
            {
                int lastDotIndex = lineText.LastIndexOf('.');
                return textArea.Caret.Offset - (textArea.Caret.Offset - textArea.Document.GetLineByOffset(textArea.Caret.Offset).Offset - lastDotIndex - 1);
            }
            
            // 查找最后一个可能的标识符开始位置
            var match = Regex.Match(lineText, @"[A-Za-z_][A-Za-z0-9_]*$|[\.\[\(]$");
            if (match.Success)
            {
                return textArea.Caret.Offset - match.Length;
            }
            return textArea.Caret.Offset;
        }

        /// <summary>
        /// 根据当前上下文获取可能的补全项
        /// </summary>
        /// <param name="lineText">当前行文本</param>
        /// <param name="prefix">当前输入的前缀</param>
        /// <returns>补全项列表</returns>
        private IEnumerable<ICompletionData> GetCompletions(string lineText, string prefix)
        {
            var result = new List<PythonCompletionData>();

            // 检查是否正在输入点号后的成员
            bool isMemberAccess = lineText.EndsWith(".") || Regex.IsMatch(lineText, @"\.\s*$");
            
            // 检查是否是导入语句
            bool isImport = Regex.IsMatch(lineText, @"^import\s+.*$") || 
                            Regex.IsMatch(lineText, @"^from\s+.*\s+import\s+.*$");

            // 处理成员访问，如 object.xxx
            if (isMemberAccess)
            {
                // 现在只使用静态分析
                // 尝试提取对象类型
                string objectType = ExtractObjectType(lineText);
                
                if (!string.IsNullOrEmpty(objectType))
                {
                    // 提供该对象类型的成员
                    ProvideMemberCompletions(result, objectType, prefix);
                }
                else
                {
                    // 如果无法确定对象类型，提供通用方法
                    ProvideCommonMethodCompletions(result, prefix);
                }
                
                return result;
            }

            // 检查是否是代码片段
            if (!isMemberAccess && !isImport && !string.IsNullOrEmpty(prefix))
            {
                foreach (var snippet in CodeSnippets)
                {
                    if (snippet.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                    {
                        result.Add(new PythonCompletionData(
                            snippet.Key, 
                            $"Python 代码片段: {snippet.Key}", 
                            snippet.Value));
                    }
                }
            }

            // 提供Python关键字
            foreach (var keyword in PythonKeywords)
            {
                if (string.IsNullOrEmpty(prefix) || keyword.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    result.Add(new PythonCompletionData(keyword, "Python关键字"));
                }
            }

            // 提供Python内置函数
            foreach (var builtin in PythonBuiltins)
            {
                if (string.IsNullOrEmpty(prefix) || builtin.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    result.Add(new PythonCompletionData(builtin, "Python内置函数"));
                }
            }

            // 提供常用模块
            if (!isMemberAccess)
            {
                foreach (var module in CommonModules)
                {
                    if (string.IsNullOrEmpty(prefix) || module.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                    {
                        result.Add(new PythonCompletionData(module, "Python模块"));
                    }
                }
            }

            // 如果是导入语句，提供模块名
            if (isImport)
            {
                foreach (var module in CommonModules)
                {
                    if (string.IsNullOrEmpty(prefix) || module.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                    {
                        result.Add(new PythonCompletionData(module, "Python模块"));
                    }
                }
            }

            return result;
        }
        
        /// <summary>
        /// 从行文本中提取对象引用
        /// </summary>
        /// <param name="lineText">当前行文本</param>
        /// <returns>对象引用文本</returns>
        private string ExtractObjectReference(string lineText)
        {
            // 查找最后一个点之前的表达式
            if (!lineText.Contains("."))
                return string.Empty;
                
            // 从末尾向前查找点号
            int lastDotIndex = lineText.LastIndexOf('.');
            if (lastDotIndex <= 0)
                return string.Empty;
                
            // 提取点号之前的部分
            string beforeDot = lineText.Substring(0, lastDotIndex).Trim();
            
            // 处理复杂表达式，如a().b.c
            // 为了简单起见，我们直接返回整个点之前的部分
            return beforeDot;
        }
        
        /// <summary>
        /// 尝试确定对象的类型
        /// </summary>
        /// <param name="lineText">当前行文本</param>
        /// <returns>对象类型字符串，如果无法确定则返回空字符串</returns>
        private string ExtractObjectType(string lineText)
        {
            if (!lineText.Contains("."))
                return string.Empty;
                
            // 从末尾向前查找点号
            int lastDotIndex = lineText.LastIndexOf('.');
            if (lastDotIndex <= 0)
                return string.Empty;
                
            // 提取点号之前的部分
            string beforeDot = lineText.Substring(0, lastDotIndex).Trim();
            
            // 处理简单赋值，如 str_val = "hello"; str_val.
            var match = Regex.Match(_currentEditorText, $@"({Regex.Escape(beforeDot)})\s*=\s*[""'].*?[""']");
            if (match.Success)
                return "str";
                
            // 处理列表赋值
            match = Regex.Match(_currentEditorText, $@"({Regex.Escape(beforeDot)})\s*=\s*\[");
            if (match.Success)
                return "list";
                
            // 处理字典赋值
            match = Regex.Match(_currentEditorText, $@"({Regex.Escape(beforeDot)})\s*=\s*\{{");
            if (match.Success)
                return "dict";
            
            // 简单模块导入
            foreach (var module in CommonModules)
            {
                if (beforeDot == module || beforeDot.EndsWith($".{module}"))
                {
                    return module;
                }
            }
            
            return string.Empty;
        }
        
        /// <summary>
        /// 为特定对象类型提供成员补全
        /// </summary>
        /// <param name="result">要添加补全项的列表</param>
        /// <param name="objectType">对象类型</param>
        /// <param name="prefix">当前输入的前缀</param>
        private void ProvideMemberCompletions(List<PythonCompletionData> result, string objectType, string prefix)
        {
            // 如果有该对象的预定义成员
            if (CommonObjectMembers.TryGetValue(objectType.ToLower(), out var members))
            {
                foreach (var member in members)
                {
                    if (string.IsNullOrEmpty(prefix) || member.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                    {
                        string description = member.EndsWith("()")
                            ? $"{objectType}的方法"
                            : $"{objectType}的属性";
                        result.Add(new PythonCompletionData(member, description));
                    }
                }
            }
            else
            {
                // 如果没有预定义成员，提供通用方法
                ProvideCommonMethodCompletions(result, prefix);
            }
        }
        
        /// <summary>
        /// 提供通用方法补全
        /// </summary>
        /// <param name="result">要添加补全项的列表</param>
        /// <param name="prefix">当前输入的前缀</param>
        private void ProvideCommonMethodCompletions(List<PythonCompletionData> result, string prefix)
        {
            foreach (var method in CommonMethodNames)
            {
                if (string.IsNullOrEmpty(prefix) || method.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    result.Add(new PythonCompletionData(method, "通用方法"));
                }
            }
        }
    }
} 